/*
Copyright SecureKey Technologies Inc. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/

package endpoint

import (
	"time"

	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/common/errors/retry"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/util/endpoint"
)

// ClientConfig 客户端配置
type ClientConfig struct {
	Organization string
	TLSCerts     ClientTLSConfig
}

// ClientTLSConfig 客户端tls
type ClientTLSConfig struct {
	Client endpoint.TLSKeyPair
}

// ConsenserConfig 共识节点配置
type ConsenserConfig struct {
	URL         string
	GRPCOptions map[string]interface{}
	TLSCACerts  endpoint.TLSConfig
}

// InodeConfig inode配置
type InodeConfig struct {
	URL         string
	GRPCOptions map[string]interface{}
	TLSCACerts  endpoint.TLSConfig
}

// OrganizationConfig 组织配置
type OrganizationConfig struct {
	IAMID                  string
	CryptoPath             string
	Users                  map[string]endpoint.TLSKeyPair
	Inodes                 []string
	CertificateAuthorities []string
}

// ChainEndpointConfig 链节点配置
type ChainEndpointConfig struct {
	Consensers []string
	Inodes     map[string]InodeChainConfig
	Policies   ChainPolicies
}

// ChainPolicies defines list of policies defined for a chain
type ChainPolicies struct {
	//Policy for querying chain block
	QueryChainConfig QueryChainConfigPolicy
	//Policy for querying discovery
	Discovery DiscoveryPolicy
	//Policy for endorser selection
	Selection SelectionPolicy
	//Policy for event service
	EventService EventServicePolicy
}

// QueryChainConfigPolicy defines opts for chainConfigBlock
type QueryChainConfigPolicy struct {
	MinResponses int
	MaxTargets   int
	RetryOpts    retry.Opts
}

// DiscoveryPolicy defines policy for discovery
type DiscoveryPolicy struct {
	MinResponses int
	MaxTargets   int
	RetryOpts    retry.Opts
}

// SelectionSortingStrategy is the endorser selection sorting strategy
type SelectionSortingStrategy string

const (
	// BlockHeightPriority (default) is a load-balancing selection sorting strategy
	// which also prioritizes inodes at a block height that is above a certain "lag" threshold.
	BlockHeightPriority SelectionSortingStrategy = "BlockHeightPriority"

	// Balanced is a load-balancing selection sorting strategy
	Balanced SelectionSortingStrategy = "Balanced"
)

// BalancerType is the load-balancer type
type BalancerType string

const (
	// RoundRobin (default) chooses endorsers in a round-robin fashion
	RoundRobin BalancerType = "RoundRobin"

	// Random chooses endorsers randomly
	Random BalancerType = "Random"
)

// SelectionPolicy defines policy for selection
type SelectionPolicy struct {
	// SortingStrategy is the endorser sorting strategy to use
	SortingStrategy SelectionSortingStrategy

	// BalancerType is the balancer to use in order to load-balance calls to endorsers
	Balancer BalancerType

	// BlockHeightLagThreshold is the number of blocks from the highest block number of a group of inodes
	// that a inode can lag behind and still be considered to be up-to-date. These inodes will be sorted
	// using the given Balancer. If a inode's block height falls behind this threshold then it will be
	// demoted to a lower priority list of inodes which will be sorted according to block height.
	// Note: This property only applies to BlockHeightPriority sorter
	BlockHeightLagThreshold int
}

// EventServicePolicy specifies the policy for the event service
type EventServicePolicy struct {
	ResolverStrategy                 string
	MinBlockHeightResolverMode       string
	Balancer                         BalancerType
	BlockHeightLagThreshold          int
	InodeMonitor                     string
	ReconnectBlockHeightLagThreshold int
	InodeMonitorPeriod               time.Duration
}

// InodeChainConfig defines the inode capabilities
type InodeChainConfig struct {
	EndorsingInode bool
	ContractQuery  bool
	LedgerQuery    bool
	EventSource    bool
}

// MatchConfig contains match pattern and substitution pattern
// for pattern matching of network configured hostnames or chain names with static config
type MatchConfig struct {
	Pattern string

	// these are used for hostname mapping
	URLSubstitutionExp                  string
	SSLTargetOverrideURLSubstitutionExp string
	MappedHost                          string

	// this is used for Name mapping instead of hostname mappings
	MappedName string

	//IgnoreEndpoint option to exclude given entity from any kind of search or from entity list
	IgnoreEndpoint bool
}
